import * as auth from "../auth-provider";
import qs from "qs";
import { useAuth } from "../context/auth-context";
import { useCallback } from "react";

const apiUrl = process.env.REACT_APP_API_URL;

interface Config extends RequestInit {
  token?: string;
  data?: object;
}

//Config={} 有默认值 自动变为可选
// http()是用来发起http请求 返回对应data,token的全部数据
export const http = async (
  endpoint: string,
  { data, token, headers, ...customConfig }: Config = {}
) => {
  console.log("data", data);

  const config = {
    method: "GET",
    headers: {
      Authorization: token ? `Bearer ${token}` : "",
      "Contend-Type": data ? "application" : "",
    },
    ...customConfig,
  };
  if (config.method.toUpperCase() === "GET") {
    endpoint += `?${qs.stringify(data)}`;
  } else {
    config.body = JSON.stringify(data || {});
  }

  //axios 和 fetch 的表现不一样，axios可以直接在返回状态不为2XX的时候抛出异常
  return window
    .fetch(`${apiUrl}/${endpoint}`, config)
    .then(async (response) => {
      if (response.status === 401) {
        await auth.logout();
        window.location.reload(); //页面重新加载
        return Promise.reject({ message: "请重新登录" });
      }
      const data = await response.json();
      if (response.ok) {
        console.log("httpdata", data);
        return data;
      } else {
        return Promise.reject(data);
      }
    });
};

// 从全局状态里取出 user 的 token 信息，组合成一个自定义 hooks，使得每次请求都携带 token 信息进行验证
export const useHttp = () => {
  const { user } = useAuth();
  return useCallback(
    (...[endpoint, config]: Parameters<typeof http>) =>
      http(endpoint, { ...config, token: user?.token }),
    ["user?.token"]
  );

  /*return ([endpoint,config]:[string,Config]) =>
         http(endpoint,{...config,token:user?user.token})*/
};

//类型别名，interface 在这种情况下没法代替type
// type FavoriteNumber = string | number
// let roseFavoriteNumber:FavoriteNumber = 16

//interface 也没法实现Utility type
// type Person = {
//     name:string,
//     age:number
// }
// const  xiaoMing:Partial<Person> = {}
// const shenMiRen:Omit<Person,'name' | 'age> = {}
